package com.ubi.core.framework;

import com.mysql.jdbc.Driver;
import com.ubi.core.database.pagination.MySqlDialect;
import com.ubi.core.database.pagination.PaginationInterceptor;
import com.ubi.core.framework.job.Scheduler;
import com.ubi.core.framework.settings.CacheSettings;
import com.ubi.core.framework.settings.ModuleSettings;
import com.ubi.core.framework.spring.PropertyContext;
import com.ubi.core.framework.spring.SpringObjectFactory;
import com.ubi.core.json.JsonConverter;
import org.apache.commons.dbcp.BasicDataSource;
import org.apache.ibatis.plugin.Interceptor;
import org.mybatis.spring.SqlSessionFactoryBean;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.EnvironmentAware;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Primary;
import org.springframework.core.env.ConfigurableEnvironment;
import org.springframework.core.env.PropertiesPropertySource;
import org.springframework.core.io.Resource;
import org.springframework.core.io.support.PathMatchingResourcePatternResolver;
import org.springframework.jdbc.datasource.DataSourceTransactionManager;
import org.springframework.transaction.PlatformTransactionManager;

import javax.annotation.PostConstruct;
import javax.sql.DataSource;
import java.io.IOException;
import java.util.Properties;

public abstract class AbstractAppConfig implements EnvironmentAware {

    @Autowired
    ConfigurableEnvironment environment;

    // public abstract DataSource dataSource();

    @Bean
    public static PropertyContext propertyContext() throws IOException {
        PropertyContext propertySource = new PropertyContext();
        propertySource.setLocations(new PathMatchingResourcePatternResolver().getResources("classpath*:*.properties"));
        propertySource.loadAllProperties();
        return propertySource;
    }

    // @Bean(name = "siteDataSource")
    // public DataSource siteDataSource() {
    // BasicDataSource dataSource = new BasicDataSource();
    // dataSource.setDriverClassName(Driver.class.getName());
    // dataSource.setUrl(environment.getRequiredProperty("site.jdbc.url"));
    // dataSource.setUsername(environment.getRequiredProperty("site.jdbc.username"));
    // dataSource.setPassword(environment.getRequiredProperty("site.jdbc.password"));
    // dataSource.setMaxActive(environment.getRequiredProperty("site.jdbc.max.active",
    // Integer.class));
    // dataSource.setDefaultAutoCommit(false);
    // return dataSource;
    // }
    //
    // @Bean
    // public MultipleDataSource multiDataSource() {
    // Map<Object, Object> targetDataSources = new HashMap<>();
    // targetDataSources.put("siteDataSource", siteDataSource());
    // targetDataSources.put("dataSource", dataSource());
    //
    // MultipleDataSource multipleDataSource = new MultipleDataSource();
    // multipleDataSource.setDefaultTargetDataSource(dataSource());
    // multipleDataSource.setTargetDataSources(targetDataSources);
    // return multipleDataSource;
    // }

    @Bean(name = "dataSource")
    public DataSource dataSource() {
        BasicDataSource dataSource = new BasicDataSource();
        dataSource.setDriverClassName(Driver.class.getName());
        dataSource
                .setUrl("jdbc:mysql://rm-wz91a7sb286i03aixo.mysql.rds.aliyuncs.com:3306/ubi-dev?characterEncoding=UTF-8");
        dataSource.setUsername("ubidev");
        dataSource.setPassword("BESTtime1!!");
        dataSource.setMaxActive(20);
        dataSource.setDefaultAutoCommit(false);
        return dataSource;
    }

    @Bean
    public ModuleSettings moduleSettings() {
        return ModuleSettings.DEFAULT;
    }

    @Bean
    public CacheSettings cacheSettings() {
        return new CacheSettings();
    }

    @Bean(name = "transactionManager")
    @Primary
    public PlatformTransactionManager transactionManager() {
        DataSourceTransactionManager dataSourceTransactionManager = new DataSourceTransactionManager();
        dataSourceTransactionManager.setDataSource(dataSource());
        return dataSourceTransactionManager;
    }

    @Bean(name = "sqlSessionFactoryBean")
    public SqlSessionFactoryBean sqlSessionFactoryBean() throws Exception {
        SqlSessionFactoryBean sqlSessionFactoryBean = new SqlSessionFactoryBean();

        sqlSessionFactoryBean.setDataSource(dataSource());
        sqlSessionFactoryBean.setPlugins(new Interceptor[]{paginationInterceptor()});

        Properties properties = new Properties();
        properties.setProperty("mapUnderscoreToCamelCase", Boolean.TRUE.toString());
        sqlSessionFactoryBean.setConfigurationProperties(properties);

        Resource[] mapperResources = new PathMatchingResourcePatternResolver()
                .getResources("classpath*:mapper/*Mapper.xml");
        sqlSessionFactoryBean.setMapperLocations(mapperResources);

        return sqlSessionFactoryBean;
    }

    @Bean
    public PaginationInterceptor paginationInterceptor() {
        PaginationInterceptor paginationInterceptor = new PaginationInterceptor();
        paginationInterceptor.setDialect(new MySqlDialect());
        return paginationInterceptor;
    }

    @PostConstruct
    public void configureEnvironment() throws IOException {
        environment.setIgnoreUnresolvableNestedPlaceholders(true);
        Properties properties = propertyContext().getAllProperties();
        environment.getPropertySources().addLast(new PropertiesPropertySource("properties", properties));
    }

    @Bean
    public SpringObjectFactory springObjectFactory() {
        return new SpringObjectFactory();
    }

//    @Bean
//    public ConverterFactory converterFactory() {
//        return new ConverterFactory();
//    }

    @Bean
    public JsonConverter jsonConverter() {
        return new JsonConverter();
    }

    @Bean
    public Scheduler scheduler() {
        return new Scheduler();
    }


}
